from django.conf import settings
from django.db.models import Avg, Sum, Count, Max, Min, Q, F

from rest_framework import serializers
from rest_framework.serializers import *
from rest_framework.validators import UniqueValidator, UniqueTogetherValidator  # 验证器

from mysqldb.models import *
from mysqldb.serializers import ListDjangoFilterBackend


class NoneSerializer(serializers.Serializer):
    """无序列化"""

    class Meta:
        fields = "__all__"


class PlaceSerializer(serializers.Serializer):
    """场所序列化"""

    pid = IntegerField(allow_null=True, required=True, help_text="场所ID")

    class Meta:
        fields = "__all__"

    def validate(self, attrs):
        try:
            r = AllinpayPlaceList.objects.get(id=attrs.get("pid"), status=1)
        except BaseException as err:
            raise serializers.ValidationError("场所不存在")
        return attrs


class ReqsnNoneSerializer(serializers.Serializer):
    """无序列化"""

    reqsn = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="单号",
    )

    class Meta:
        fields = "__all__"


class AllinpayStaffRegisterSerializer(serializers.Serializer):
    """员工注册"""

    phone = RegexField(
        r"^1[23456789]\d{9}$",
        help_text="移动电话号码，后台登录账号",
        validators=[UniqueValidator(queryset=AllinpayStaffList.objects.all())],
    )
    password = CharField(max_length=4, help_text="验证码")

    class Meta:
        fields = "__all__"


class AllinpayStaffListSerializer(serializers.ModelSerializer):
    """员工列表"""

    id = IntegerField(label="ID", read_only=True)
    # status = IntegerField(max_value=1, min_value=0, default=0, help_text="员工状态")
    nicename = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="员工昵称",
    )
    basename = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="真实姓名",
    )
    icon = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="员工头像",
    )
    phone = RegexField(
        r"^1[23456789]\d{9}$",
        help_text="移动电话号码，后台登录账号",
        validators=[UniqueValidator(queryset=AllinpayStaffList.objects.all())],
    )
    idcode = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="身份证号",
        validators=[UniqueValidator(queryset=AllinpayStaffList.objects.all())],
    )
    telent = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        help_text="紧急联系人",
    )
    openid = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="微信openid",
    )
    bankname = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="银行名称",
    )
    bankcard = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="银行卡号",
    )
    bankaddr = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="开户银行",
    )
    bankcode = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="银联行号",
    )
    created = DateTimeField(default=CreateOnlyDefault(timezone.now), help_text="创建时间")
    modifed = DateTimeField(default=timezone.now, help_text="编辑时间")
    status = ReadOnlyField()

    class Meta:
        model = AllinpayStaffList
        fields = "__all__"


class AllinpayPlaceinterListSerializer(serializers.ModelSerializer):
    """员工积分列表"""

    id = IntegerField(label="ID", read_only=True)
    pid = IntegerField(help_text="场所ID")
    sid = IntegerField(help_text="员工真实ID")
    intertype = IntegerField(help_text="积分类型ID")
    intersum = IntegerField(allow_null=True, default=0, help_text="当前分值")
    hash = CharField(read_only=True, help_text="校验码")
    currenttime = DateTimeField(read_only=True, default=timezone.now, help_text="变更时间")
    maxinter = IntegerField(allow_null=True, default=0, help_text="累计分值")
    maxhash = CharField(read_only=True, help_text="校验码")

    staff = SerializerMethodField()
    inters = SerializerMethodField()

    class Meta:
        model = AllinpayPlaceinterList
        fields = "__all__"

    def get_staff(self, attr):
        try:
            r = AllinpayStaffList.objects.get(id=attr.sid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def get_inters(self, attr):
        try:
            r = AllinpayIntegralList.objects.get(id=attr.intertype)
        except BaseException as err:
            return ""
        else:
            return r.name

    def validate_intertype(self, attr):
        if not attr in list(
            AllinpayIntegralList.objects.all().values_list("id", flat=True)
        ):
            raise serializers.ValidationError("积分类型ID错误")
        return attr

    def validate(self, attrs):
        attrs = dict(attrs)
        try:
            r = AllinpayPlacestaffList.objects.get(
                pid=attrs.get("pid"), sid=attrs.get("sid"), status=1
            )
        except BaseException as err:
            raise serializers.ValidationError("查询场所员工失败")
        return attrs


class AllinpayPlaceinterLogSerializer(serializers.ModelSerializer):
    """员工积分日志"""

    id = IntegerField(label="ID", read_only=True)
    pid = IntegerField(help_text="场所ID")
    sid = IntegerField(help_text="员工真实ID")
    intertype = IntegerField(help_text="积分类型ID")
    inter = IntegerField(default=0, help_text="当前分值")
    intersum = IntegerField(default=0, help_text="累计分值")
    currenttime = DateTimeField(read_only=True, default=timezone.now, help_text="创建时间")
    reqsn = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="单号",
    )
    msgtype = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="单据类型",
    )
    status = IntegerField(default=0, help_text="当前状态0,1,2")
    curentimg = DateTimeField(default=timezone.now, help_text="变更时间")
    post = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="兑换单号",
    )

    staff = SerializerMethodField()
    inters = SerializerMethodField()

    class Meta:
        model = AllinpayPlaceinterLog
        fields = "__all__"

    def get_staff(self, attr):
        try:
            r = AllinpayStaffList.objects.get(id=attr.sid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def get_inters(self, attr):
        try:
            r = AllinpayIntegralList.objects.get(id=attr.intertype)
        except BaseException as err:
            return ""
        else:
            return r.name

    def validate_intertype(self, attr):
        if not attr in list(
            AllinpayIntegralList.objects.all().values_list("id", flat=True)
        ):
            raise serializers.ValidationError("积分类型ID错误")
        return attr

    def validate(self, attrs):
        attrs = dict(attrs)
        try:
            r = AllinpayPlacestaffList.objects.get(
                pid=attrs.get("pid"), sid=attrs.get("sid"), status=1
            )
        except BaseException as err:
            raise serializers.ValidationError("查询场所员工失败")
        return attrs


class AllinpayPlaceinterAddsSerializer(serializers.ModelSerializer):
    """员工积分奖励"""

    id = IntegerField(label="ID", read_only=True)
    reqsn = ReadOnlyField()
    pid = IntegerField(help_text="场所ID")
    sid = IntegerField(help_text="员工ID")
    intertype = IntegerField(help_text="积分类型")
    integral = IntegerField(max_value=100, min_value=0, help_text="分值")
    answer = ReadOnlyField(help_text="创建者ID")
    checker = ReadOnlyField(help_text="审核者ID")
    status = ReadOnlyField(help_text="状态")
    curentime = DateTimeField(read_only=True, help_text="创建时间")
    modified = DateTimeField(read_only=True, help_text="审核时间")
    bem = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="备注信息",
    )
    intName = SerializerMethodField()

    class Meta:
        model = AllinpayPlaceinterAdds
        fields = "__all__"

    def get_intName(self, attr):
        try:
            r = AllinpayIntegralList.objects.get(id=attr.intertype)
        except BaseException as err:
            return ""
        else:
            return r.name

    def validate_intertype(self, attr):
        if not attr in list(
            AllinpayIntegralList.objects.all().values_list("id", flat=True)
        ):
            raise serializers.ValidationError("积分类型ID错误")
        if attr > 4:
            raise serializers.ValidationError("积分类型ID超出范围")
        return attr

    def validate(self, attrs):
        attrs = dict(attrs)
        try:
            r = AllinpayPlacestaffList.objects.get(
                pid=attrs.get("pid"), sid=attrs.get("sid"), status=1
            )
        except BaseException as err:
            raise serializers.ValidationError("查询场所员工失败")
        return attrs


class AllinpayPlaceinterAddsCheakedSerializer(serializers.Serializer):
    """无序列化"""

    ckid = IntegerField(help_text="积分奖励记录ID")

    class Meta:
        fields = "__all__"


# print(repr(AllinpayPlaceinterAddsSerializer()))


class AllinpayInterConvertSerializer(serializers.Serializer):
    """积分兑换"""

    pid = IntegerField(help_text="员工绑定ID")
    sid = IntegerField(help_text="员工绑定ID")
    intertype = IntegerField(help_text="积分类型ID")
    money = IntegerField(help_text="兑换金额(RMB分)")

    # pid = SerializerMethodField()
    # sid = SerializerMethodField()

    class Meta:
        fields = "__all__"

    # def get_pid(self, attrs):
    #     try:
    #         r = AllinpayPlacestaffList.objects.get(id=attrs["psid"], status=1)
    #     except BaseException as err:
    #         return None
    #     else:
    #         return r.pid

    # def get_sid(self, attrs):
    #     try:
    #         r = AllinpayPlacestaffList.objects.get(id=attrs["psid"], status=1)
    #     except BaseException as err:
    #         return None
    #     else:
    #         return r.sid


class AllinpayPlaceinterPostSerializer(serializers.ModelSerializer):
    """员工积分兑换单"""

    id = IntegerField(label="ID", read_only=True)
    reqsn = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="兑换单号",
    )
    pid = IntegerField(allow_null=True, help_text="场所ID")
    sid = IntegerField(allow_null=True, help_text="员工ID")
    answer = IntegerField(allow_null=True, help_text="操作员ID")
    intertype = IntegerField(allow_null=True, help_text="积分类型")
    integral = IntegerField(allow_null=True, help_text="分值")
    money = IntegerField(allow_null=True, help_text="兑换金额")
    curentime = DateTimeField(allow_null=True, required=False, help_text="兑换时间")
    status = IntegerField(default=0, help_text="状态")
    modified = DateTimeField(allow_null=True, required=False, help_text="编辑时间")

    staff = SerializerMethodField()
    answers = SerializerMethodField()
    inters = SerializerMethodField()

    class Meta:
        model = AllinpayPlaceinterPost
        fields = "__all__"

    def get_staff(self, attr):
        try:
            r = AllinpayStaffList.objects.get(id=attr.sid)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def get_answers(self, attr):
        try:
            r = AllinpayStaffList.objects.get(id=attr.answer)
        except BaseException as err:
            return ""
        else:
            return r.basename

    def get_inters(self, attr):
        try:
            r = AllinpayIntegralList.objects.get(id=attr.intertype)
        except BaseException as err:
            return ""
        else:
            return r.name


class AllinpayPlaceinterNoneSerializer(serializers.Serializer):
    """创建员工积分兑换单请求"""

    pid = IntegerField(allow_null=True, help_text="场所ID")
    sid = IntegerField(allow_null=True, help_text="员工ID")
    intertype = IntegerField(allow_null=True, help_text="积分类型")
    data = ListField(child=IntegerField(), help_text="记录ID列表")

    class Meta:
        fields = "__all__"


# ===============================================================
# 团队
# ===============================================================


class AllinpayStaffteamListSerializer(serializers.ModelSerializer):
    """团队列表"""

    id = IntegerField(label="ID", read_only=True)
    pid = IntegerField(allow_null=True, required=True, help_text="场所ID")
    name = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=True,
        help_text="团队名称",
    )
    staffs = ListField(child=CharField(), allow_null=True, help_text="成员SID列表")
    status = IntegerField(
        allow_null=True, max_value=1, min_value=0, default=1, help_text="状态"
    )
    master = IntegerField(allow_null=True, required=False, help_text="团长SID")
    bem = CharField(
        allow_blank=True,
        allow_null=True,
        max_length=255,
        required=False,
        help_text="团队口号",
    )

    Masters = SerializerMethodField()
    Members = SerializerMethodField()

    class Meta:
        model = AllinpayStaffteamList
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=AllinpayStaffteamList.objects.all(), fields=("pid", "name")
            )
        ]

    def validate(self, attrs):
        try:
            p = AllinpayPlaceList.objects.get(id=attrs.get("pid"), status=1)
            if attrs.get("master"):
                s = AllinpayPlacestaffList.objects.get(
                    pid=p.id, sid=attrs.get("master"), status=1
                )
                if not str(attrs.get("master")) in attrs.get("staffs"):
                    raise serializers.ValidationError("该团长非团队成员")
            if attrs.get("staffs"):
                u = AllinpayPlacestaffList.objects.filter(
                    pid=p.id, status=1, sid__in=attrs.get("staffs")
                )
                if not u.count() == len(attrs.get("staffs")):
                    raise serializers.ValidationError("查询成员SID异常")
                for i in attrs.get("staffs"):
                    c = AllinpayStaffteamList.objects.filter(
                        pid=p.id, staffs__icontains=f"{i}"
                    ).exclude(pid=p.id, name=attrs.get("name"))
                    if c.count() > 0:
                        raise serializers.ValidationError("员工ID重复,已加入其他团队")
        except AllinpayPlaceList.DoesNotExist as err:
            raise serializers.ValidationError(f"查询场所异常 {err}")
        except AllinpayPlacestaffList.DoesNotExist as err:
            raise serializers.ValidationError(f"查询团长异常 {err}")
        except BaseException as err:
            raise serializers.ValidationError(f"未知异常 {err}")
        return attrs

    def get_Masters(self, obj):
        """低优先级"""
        try:
            r = AllinpayStaffList.objects.get(id=obj.master)
        except BaseException as err:
            return ""
        else:
            return {"id": r.id, "name": r.basename}

    def get_Members(self, obj):
        """低优先级"""
        users = (
            [int(s) for s in eval(obj.staffs) if type(s) == str]
            if type(obj.staffs) == str
            else obj.staffs
        )
        try:
            s = AllinpayStaffList.objects.filter(id__in=users).values("id", "basename")
        except BaseException as err:
            return None
        else:
            return s

    def to_representation(self, instance):
        """高优先级"""
        ret = super().to_representation(instance)
        if ret.get("staffs"):
            ret["staffs"] = [
                int(x) for x in eval(str(instance.staffs)) if type(x) == str
            ]
        return ret


# ===============================================================
# 全民激励
# ===============================================================


class GIncentivesConfSerializer(serializers.ModelSerializer):
    """全民激励配置"""

    id = IntegerField(label="ID", read_only=True)
    pid = IntegerField(allow_null=True, required=True, help_text="场所ID")
    tid = IntegerField(allow_null=True, required=True, help_text="团队ID")
    sid = IntegerField(allow_null=True, required=True, help_text="员工ID")
    status = IntegerField(allow_null=True, max_value=1, min_value=0, default=1)
    level1 = IntegerField(allow_null=True, min_value=0, default=0)
    level2 = IntegerField(allow_null=True, min_value=0, default=0)
    level3 = IntegerField(allow_null=True, min_value=0, default=0)

    # achieve = SerializerMethodField()
    place = SerializerMethodField()
    teams = SerializerMethodField()
    staff = SerializerMethodField()

    class Meta:
        model = GIncentivesConf
        fields = "__all__"

    def validata(self, attrs):
        pid, tid, sid = attrs.get("pid"), attrs.get("tid"), attrs.get("sid")
        if not tid and not sid:
            raise serializers.ValidationError("tid和sid不能同时为空")
        if tid:
            try:
                r = AllinpayStaffteamList.objects.get(id=tid, pid=pid)
            except BaseException as err:
                raise serializers.ValidationError("tid错误")
        if sid:
            try:
                r = AllinpayPlacestaffList.objects.get(pid=pid, sid=sid)
            except BaseException as err:
                raise serializers.ValidationError("sid错误")
        return attrs

    def get_achieve(self, obj):
        try:
            r = GIncentivesList.objects.get(
                Q(pid=obj.pid) & Q(tid=obj.tid) | Q(sid=obj.sid)
            )
        except BaseException as err:
            return None
        return GIncentivesListSerializer(r).data

    def get_place(self, obj):
        try:
            r = AllinpayPlaceList.objects.get(id=obj.pid)
        except BaseException as err:
            return None
        return r.name

    def get_teams(self, obj):
        try:
            r = AllinpayStaffteamList.objects.get(id=obj.tid)
        except BaseException as err:
            return None
        return r.name

    def get_staff(self, obj):
        try:
            r = AllinpayStaffList.objects.get(id=obj.sid)
        except BaseException as err:
            return None
        return r.basename


class GIncentivesListSerializer(serializers.ModelSerializer):
    """成就榜单"""

    id = IntegerField(label="ID", read_only=True)
    pid = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=True
    )
    tid = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=True
    )
    sid = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=True
    )
    present = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    status = IntegerField(
        allow_null=True, max_value=2147483647, min_value=-2147483648, required=False
    )
    nowdate = DateField(allow_null=True, required=False)
    finish1 = DateTimeField(allow_null=True, required=False)
    finish2 = DateTimeField(allow_null=True, required=False)
    finish3 = DateTimeField(allow_null=True, required=False)

    place = SerializerMethodField()
    teams = SerializerMethodField()
    staff = SerializerMethodField()
    conf = SerializerMethodField()

    class Meta:
        model = GIncentivesList
        fields = "__all__"
        validators = [
            UniqueTogetherValidator(
                queryset=GIncentivesList.objects.all(), fields=("pid", "tid")
            ),
            UniqueTogetherValidator(
                queryset=GIncentivesList.objects.all(), fields=("pid", "sid")
            ),
        ]

    def get_place(self, obj):
        try:
            r = AllinpayPlaceList.objects.get(id=obj.pid)
        except BaseException as err:
            return None
        return r.name

    def get_teams(self, obj):
        try:
            r = AllinpayStaffteamList.objects.get(id=obj.tid)
        except BaseException as err:
            return None
        return r.name

    def get_staff(self, obj):
        try:
            r = AllinpayStaffList.objects.get(id=obj.sid)
        except BaseException as err:
            return None
        return r.basename

    def get_conf(self, obj):
        try:
            r = GIncentivesConf.objects.get(
                Q(pid=obj.pid) & Q(tid=obj.tid) | Q(sid=obj.sid)
            )
        except BaseException as err:
            return None
        return GIncentivesConfSerializer(r).data


# print(repr(GIncentivesListSerializer()))
